#include "Hexen_Win32.h"

Hexen::Hexen(void) {
	init();
	startupScreen(false);
}

Hexen::Hexen( std::string ip ) {
	init();
	startupScreen(false);
	connectTo(ip);
}

Hexen::Hexen(std::string nick, std::string ip) {
	init();
	startupScreen(false);
	username = nick;
	connectTo(ip);
}

//Destructor
Hexen::~Hexen( void )
{
	
	
	
}

void Hexen::init() {
	window = initscr();
	keypad(window, TRUE);
	noecho();
	getmaxyx(window, rows, cols);
	username = "n00b_user";
}

void Hexen::run(void) {
	Client::run();
}

void Hexen::startupScreen(bool splash) {
	erase();
	int centered_x = (cols-49)/2;
	int centered_y = (rows-5)/2;
	
	// http://www.network-science.de/ascii/	
	mvprintw(0+centered_y, centered_x, "	_/	_/	By: Edward Cant & Dale Stevens");
	mvprintw(1+centered_y, centered_x, "   _/	_/	_/_/	_/	_/	_/_/	_/_/_/");
	mvprintw(2+centered_y, centered_x, "  _/_/_/_/  _/_/_/_/	_/_/	_/_/_/_/  _/	_/");
	mvprintw(3+centered_y, centered_x, " _/	_/  _/		_/	_/  _/		_/	_/");
	mvprintw(4+centered_y, centered_x, "_/	_/	_/_/_/  _/	_/	_/_/_/  _/	_/");
	mvprintw(5+centered_y, centered_x, "   			Version 2.3");
	move(rows-1, 0);
	
	refresh();
	
#ifdef __WIN32__
	if(splash)		Sleep(1);
#else
	if(splash)		sleep(1);
#endif
	else			keyTyped(getch());
	
	addLine(0, "Welcome to Hexen 2.3 - Enter /help for command listing.");
}

void Hexen::catchInput(void) {
	int ch = getch();
	switch(ch) {
		case '\n'				: keyEnter();		break;
		case KEY_LEFT			: keyLeft();		break;
		case KEY_RIGHT			: keyRight();		break;
		case KEY_UP				: keyUp();			break;
		case KEY_DOWN			: keyDown();		break;
		case KEY_DELETE			: keyDelete();		break;
		default					: keyTyped(ch);		break;
	}
}

void Hexen::updateToolbar(void) {
	attron(A_STANDOUT | A_BOLD | A_UNDERLINE);
	for (int i = 0; i < cols; i++)
		mvprintw(0, i, " ");
	if (host != NULL)
		mvprintw(0, 1, "Hexen 2.3 | Connected as Client to Server %s", inet_ntoa(*(in_addr *)host->h_addr));
	else
		mvprintw(0, 1, "Hexen 2.3 | Running Client. Not connected to any server.");
	attroff(A_STANDOUT | A_BOLD | A_UNDERLINE);
}

void Hexen::drawConversation(void) {
	erase();
	updateToolbar();
	int msg = 0, speaker;
	std::string text;
	// I totally pwned the line wrap right here... Later I guess I'll add somethign that looks for spaces to break.
	for (int line = 1; (msg < conversation.size()) && (line < rows-1); line += (int)ceil(conversation.at(scrollPos + msg - 1)->message.length()/cols) + 1) {
		
		speaker = conversation[scrollPos + msg]->speaker;
		text = conversation[scrollPos + msg]->message;
		
		if(speaker == 0) {
			attron(A_STANDOUT);
			for (int i = 0; i < cols; i++)
				mvprintw(line, i, " ");
			mvprintw(line, 1, text.c_str());
			attroff(A_STANDOUT);
		} else if(speaker == 1) {
			if(!style)
				attron(A_UNDERLINE);
			mvprintw(line, 0, text.c_str());
			if(!style)
				attroff(A_UNDERLINE);
		} else if(speaker == 2) {
			if(style)
				attron(A_BOLD);
			mvprintw(line, 0, text.c_str());
			if(style)
				attroff(A_BOLD);
		}
		msg++;
	}
	updateWindow();
}

void Hexen::addLine(int speaker, std::string m )
{
	unsigned int messages = conversation.size();
	
	Message *message = new Message();
	message->message = m;
	message->speaker = speaker;
	
	conversation.push_back(message);
	
	// We need advanced scrolling here...
	scrollPos = rows > messages+1 ? 0 : messages+1-rows+1;
	drawConversation();
}

void Hexen::clearTextField(void) {
	for(int i = 0; i < DATA_SIZE; i++)
		mvdelch(rows-1, 0);
	message[0] = '\0';
	cursor = 0;
	characters = 0;
}

void Hexen::updateWindow(void) {
	mvprintw(rows-1, 0, message);
	move(rows-1, cursor);
	refresh();
}

void Hexen::keyEnter() {
	if(strlen(message) == 0)	return;
	
	if(message[0] == '/') {
		processCommands(message);
	} else if (host != NULL) {
		addLine(1, message);
		if(host) {
			message[characters] = '\0';
			Packet packet = Packet(MESSAGE, message);
			if(!packet.release(textSock))
				addLine(0, "Connection Error.");
		}
	}
	clearTextField();
}

void Hexen::keyLeft() {
	(cursor > 0) ? cursor-- : cursor;
}

void Hexen::keyRight() {
	(cursor < DATA_SIZE) ? cursor++ : cursor;
}

void Hexen::keyUp() {
	(scrollPos > 0) ? scrollPos-- : scrollPos;
	drawConversation();
}

void Hexen::keyDown() {
	(scrollPos <= conversation.size()-rows) ? scrollPos++ : scrollPos;
	drawConversation();
}

void Hexen::keyDelete() {
	if(characters > 0) {
		if(cursor == characters) {
			mvdelch(rows-1, characters-1);
			message[characters-1] = '\0';
		} else {
			for(int i = cursor-1; i < characters; i++) {
				message[i] = message[i+1];
			}
			mvdelch(rows-1, cursor);
		}
		characters--;
		cursor--;
	}
}

void Hexen::keyTyped(int ch) {
	if(ch < 32 || ch > 127 || characters >= DATA_SIZE)	return;
	characters++;
	if(cursor == characters) {
		message[characters] = (char)ch;
	} else {
		for (int i = characters-1; i > cursor; i--) {
			message[i+1] = message[i];
		}
		message[cursor] = (char)ch;
	}
	if (characters < DATA_SIZE) message[characters] = '\0';
	cursor++;
}

void Hexen::quit(void) {
	Client::quit("");
}
